/**
 ******************************************************************************
 * @file	minishell-tiny.c
 * @brief	精简版本minishell

完整版MiniShell:
	https://github.com/MenglongWu/MiniShellEx

- 2017-6-23,MenglongWu,MenglongWoo@aliyun.com
 *
 Copyright (C) 2017 桂林聚联科技有限公司, Inc. All Rights Reserved.
*/

#include <string.h>
#include "minishell-tiny.h"


void sh_detach_xx_fmt (char *fmt, long len, struct sh_detach_depth *depth)
{
	// char *cmd[256],
	char *token = NULL;
	int   index = 0;
	// char  seps[] = " ,\t\n";

	//step 1:提取第一个单词，并在命令列表里寻找是否存在命令
	*(fmt + len) = '\0';
	token = strtok(fmt, depth->seps);

	while(token != NULL && index < depth->len) {
		depth->cmd[index] = token;
		index++;
		token = strtok(NULL, depth->seps);
	}
	depth->count = index;
}


// void sh_detach_fmt_ac (char *fmt, long len, char **cmd, int *count)
// {
// 	// char *cmd[256],
// 	char *token = NULL;
// 	int   index = 0;
// 	char  seps[] = " ,\t\n";

// 	//step 1:提取第一个单词，并在命令列表里寻找是否存在命令
// 	*(fmt + len) = '\0';
// 	token = strtok(fmt, seps);

// 	while(token != NULL) {
// 		cmd[index] = token;
// 		index++;
// 		token = strtok(NULL, seps);
// 	}
// 	*count = index;
// }


/*
when call sh_whereboot() could be set _prompt_tree[0] point new "boot_new"
boot_unuse only be use for avoid "Segmentation fault" and reminded developer call it.
*/
static struct cmd_prompt boot_unuse[] = {
	PROMPT_NODE(NULL    ,      NULL,
	(char *)"must call sh_whereboot()",
	(char *)NULL,
	(int)  NULL),
};


#define PROMPT_DEPTH (16)
struct cmd_prompt *_prompt_tree[PROMPT_DEPTH] = {boot_unuse};
int                _prompt_index = 0;
void sh_analyse_ex (char *fmt, long len, struct sh_detach_depth *depth2, void *ptr)
{
	char *cmd[256], *token = NULL;
	unsigned int count = 0;
	char seps[]   = ",\t\r \n";


	struct cmd_prompt *pstart;
	int find = 0;

	struct sh_detach_depth depth;
	depth.cmd = cmd;
	depth.len = 4;
	depth.count = 0;
	depth.seps = NULL;

	sh_detach_xx_fmt(fmt,len, depth2);
	if (depth2->count) {
		pstart = _prompt_tree[_prompt_index];
		while(pstart->name) {
			if(0 == memcmp(depth2->cmd[0], pstart->name, strlen(depth2->cmd[0]))) {
				find = 1;
				break;
			}
			pstart++;
		}

		if(find == 1) {
			if (pstart->fun) {
				pstart->fun(ptr, depth2->count, (char **)&depth2->cmd[0]);
			}
		}
		else {
			if (depth2->cmd[0][0] != '\r') {
				printf("%s: command not found\r\n", depth2->cmd[0]);
			}
			
		}
	}
	return ;
}

/*
	the function must be calld
	core know from which "struct cmd_prompt" start with.
	and then call sh_enter_ex
*/
void sh_whereboot(struct cmd_prompt *boot_new)
{
	_prompt_tree[0] = &boot_new[0];
	_prompt_index    = 0;	
}
